STRUCTURES : defining, accessing, unions, fields, linked lists
_________________________________________________________________________

Structures, also known as "records", provide the means to group related data of different types together in a convenient package.  Structures also represent the basic building blocks of C++ classes.

DEFINING STRUCTURES

A structure definition consists of the 'struct' keyword and the structure name followed by a list of variable declarations:

  struct tag
  
    variable declarations
   optional_struct_declaration;

The following is an example of a structure definition:

  struct employee
  
    char *lastName;
    char *firstName;
    char *streetAddress;
    char *city;
    char *state;
    long zipCode;
    int  employeeID;
    int  age;
  ;

The above definition only defines a structure of type 'employee'.  To declare a variable which is a structure of type 'employee', the following declaration is used:

  struct employee person; // declares and allocates memory for structure

Many times, pointers to structures are used.

  struct employee *personPtr; // declares pointer only

If your working with pointers to structures, you must follow your pointer variable declaration with code to allocate memory for the structure.  If your using straight C, you'd use 'malloc' from the ANSI library to allocate the memory for the structure like this:

  personPtr = (struct employee *)malloc( sizeof( struct employee ) );

With C++, you use the 'new' operator to allocate the memory as follows:

  personPtr = new employee;

The C++ way is obviously a better way of allocating memory and should be used in place of the old 'malloc' command.

ACCESSING STRUCTURE VARIABLES

If you've declared a structure variable, you access the variable members using the '.' member operator like this:

  person.employeeID = 10;
  person.age = 35;

You can use structure members just like any other variable.

  if( person.age > 65 )
    DoSendPinkSlip( person );

When using pointers to structures, you access the variable members using the '->' member operator in a similar manner.

  personPtr->employeeID = 10;
  personPtr->age = 35;

UNIONS

Unions allow you to store different data type in the same memory location (but not at the same time).  They follow the same syntax as structures:

  union optional_tag
  
    variable declarations
   optional_union_declaration;

The following is an example of a union definition:

  union myUnionDef
  
    int   integer;
    float real;
    char  *string;
   myUnion;

The memory allocated for a union will be large enough to hold the largest item declared in the union definition.  Unions might be a good idea for maximizing memory use, but generally, they are rarely used and should probably be avoided.

BIT FIELDS

Fields, like unions, help to maximize memory usage but in days where memory is cheap and code clarity is important, fields are used less and less.  They are implementation-dependent and create cross platform compatibility problems.  Here's an example of a field definition:

  struct sysFlags
  
    unsigned int SysFlag1 : 1;  
    unsigned int SysFlag2 : 1;
    unsigned int SystemID : 2;
    unsigned int          : 4;  // unused
    unsigned int SysFlag3 : 1;
  ;

LINKED LISTS

Linked lists are a series of structures which are usually dynamically allocated and linked together (by pointers) to maintain a bond.  Consider the following structure definition:

  struct student
  
    struct student *next;
    char           *name;
    int            id;
  ;

When defining a new student, you would "link" the student to the existing list of students by doing something like this:

  struct student *gTopOfList;    // In this example, program keeps track
  struct student *gEndOfList;    // of top and bottom of linked list.
  struct student *freshman;

  freshman = new student;

  gEndOfList->next = freshman;   // Last student is now new freshman.
  gEndOfList = freshman;         // Update global variable.
  gEndOfList->next = nil;        // Identifies end of list.

Using this example, you could print the entire student roster with the following code fragment:

  struct student *currentStudent;

  currentStudent = gTopOfList;
  do
    cout << currentStudent->name << endl;
   while( currentStudent->next != nil );

An improved linked list would include a "prev" pointer in addition to the "next" pointer.  This allows you to travel up as well as down the linked list chain of structures.  There are tree linked lists, circular linked lists, and quite possibly, an infinite number of types and combinations you could come up with.